package org.unt.genlogic;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

public class J2eeSorceCodeProjectParser {

	private static Logger log = Logger.getLogger("Files");

	private static String baseDir = "C:/FleetBox/workspace2/";
	private static List filesList = null;

	public static void main(String[] args) throws IOException {

		Map map = new HashMap();

		StringBuffer buf = new StringBuffer();

		// 17 batch projects, 6 projects for web app
		String[] projects = { "BatchCommandeInternet", "BatchPnrEcAladin", "BatchPnrEpgc", "BatchPnrIdol", "BatchPnrIdt", "BatchPnrImmat", "BatchPnrLdp",
				"BatchPnrMcq", "BatchPnrPamir", "BatchPnrPlpr", "BatchPnrPrix", "BatchPnrPurgeOjb", "BatchPnrRoot", "BatchPNRSagaiREF", "BatchPnrSitel",
				"BatchPnrSysame", "BatchPnrUniteVente", "PnrEar", "PnrMetier", "PnrRoot", "PnrSQL", "PnrWeb" };

		// Load beans and tables
		List beans = new ArrayList();
		List tables = new ArrayList();
/*
		{
			List list = Files.readFileAsList("C:/Migra DI/beans tables.txt");
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				String line = (String) iterator.next();

				beans.add(line.substring(0, line.indexOf("\t")));
				tables.add(line.substring(line.indexOf("\t") + 1));
			}
		}
*/
		// Load clauses
		List clauses = Files.readFileAsList("C:/Migra DI/clauses2.txt");

		// Iterate projects
		for (int i = 0; i < projects.length; i++) {

			log.info("Processing project " + projects[i]);

			// Get files of a project
			File dir = new File(baseDir + projects[i]);
			filesList = new ArrayList();
			Files.listFilesRecursively(dir, filesList, getBannedFiles(), getBannedExtensions(), getBannedDirs());

			// Iterate files for a project
			for (Iterator iterator = filesList.iterator(); iterator.hasNext();) {

				File file = (File) iterator.next();
				String ap = file.getAbsolutePath();
				String name = ap.substring(ap.lastIndexOf("\\") + 1);

				String key = projects[i] + "\t" + name + "\t" + ap + "\t \t";

				BufferedReader reader = new BufferedReader(new FileReader(file));
				String line;

				// Iterate line by line of a file
				while ((line = reader.readLine()) != null) {

					// Look for references for every bean and save in map
					for (Iterator iterator2 = beans.iterator(); iterator2.hasNext();) {

						String bean = (String) iterator2.next();

						if (contains(line, bean)) {

							if (!map.containsKey(key)) {
								map.put(key, new Val());
							}

							Val val = (Val) map.get(key);
							val.beans.append(bean + " ");
						}
					}

					// Look for references for every table and save in map
					for (Iterator iterator2 = tables.iterator(); iterator2.hasNext();) {

						String table = (String) iterator2.next();

						if (contains(line.toUpperCase(), table)) {

							if (!map.containsKey(key)) {
								map.put(key, new Val());
							}

							Val val = (Val) map.get(key);
							val.tables.append(table + " ");
						}
					}

					// Look for references for every clause and save in map
					for (Iterator iterator2 = clauses.iterator(); iterator2.hasNext();) {

						String clause = (String) iterator2.next();

						if (contains(line.toUpperCase(), clause)) {

							if (!map.containsKey(key)) {
								map.put(key, new Val());
							}

							Val val = (Val) map.get(key);
							val.clauses.append(clause + " ");
						}
					}
				}

				reader.close();
			}
		}

		buf = new StringBuffer();

		Set keysSet = map.keySet();
		List keysList = new ArrayList();
		keysList.addAll(keysSet);
		Collections.sort(keysList);

		for (Iterator iterator = keysList.iterator(); iterator.hasNext();) {

			String key = (String) iterator.next();
			Val val = (Val) map.get(key);
			buf.append(key + "\t" + get(val.clauses.toString()) + "\t" + get(val.tables.toString()) + "\t" + get(val.beans.toString()) + "\n");
		}

		Files.writeToFile(buf.toString(), "C:/Migra DI/An�lisis2.txt");
	}

	private static class Val {

		private Val() {
			beans = new StringBuffer();
			tables = new StringBuffer();
			clauses = new StringBuffer();
		}

		public StringBuffer beans;
		public StringBuffer tables;
		public StringBuffer clauses;
	}

	private static String get(String str) {

		if ("".equals(str)) {
			return "";
		}

		Map map = new HashMap();
		String strs[] = str.split(" ");

		for (int i = 0; i < strs.length; i++) {

			if (!map.containsKey(strs[i])) {
				map.put(strs[i], new Integer(0));
			}

			Integer amount = (Integer) map.get(strs[i]);
			map.put(strs[i], new Integer(amount.intValue() + 1));
		}

		StringBuffer buf = new StringBuffer();

		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {

			String key = (String) iterator.next();
			buf.append(key + " "); // + "(" + map.get(key) + ") ");
		}

		return buf.toString();
	}

	public static void amain(String[] args) {

		String find = "Hola";

		String[] line1 = { " Hola ", "(Hola)", "asdf ( Hola) adf", "(Hola )", " (Hola) " };
		String[] line2 = { "Hola", " Hola", "Hola ", "Holas", "sHola", "1Holas" };

		for (int i = 0; i < line1.length; i++) {

			if (!contains(line1[i], find)) {
				// if (!line1[i].matches(pattern)) {
				System.out.println("error 1 " + i);
			}
		}

		for (int i = 0; i < line2.length; i++) {

			if (contains(line2[i], find)) {
				// if (line2[i].matches(pattern)) {
				System.out.println("error 2" + i);
			}
		}
	}

	public static boolean contains(String line, String find) {

		if (line.indexOf(find) < 0) {
			return false;
		}

		// Inside a comment?
		if (line.trim().startsWith("/") || line.trim().startsWith("*")) {
			log.debug(find + "\t" + line);
			return false;
		}

		int index = line.indexOf(find);

		// Check character before and after
		boolean okBefore = index == 0 ? true : line.substring(index - 1, index).matches("\\W");
		// boolean okAfter = index + find.length() == line.length() ? true : line.substring(index + find.length(), index + find.length() + 1).matches("\\W");

		// if (!okBefore || !okAfter) {
		// log.debug(find + "\t" + line);
		// }

		return okBefore; // && okAfter;

	}

	public static Set getBannedFiles() {

		Set set = new HashSet();

		set.add("OJB-logging.properties");

		return set;
	}

	public static Set getBannedDirs() {

		Set set = new HashSet();

		set.add("target");
		set.add("CVS");
		set.add("bin");

		return set;
	}

	public static Set getBannedExtensions() {

		Set set = new HashSet();

		set.add("sh");
		set.add("js");
		set.add("apt");
		set.add("tld");
		set.add("xsd");
		set.add("css");
		set.add("xsd");
		set.add("jar");
		set.add("bat");
		set.add("doc");
		set.add("ser");
		set.add("class");
		set.add("checkstyle");
		set.add("prefs");
		set.add("htm");
		set.add("html");
		set.add("classpath");
		set.add("classpath1");
		set.add("MF");
		set.add("cvsignore");
		set.add("dtd");
		set.add("djunitplugin");
		set.add("1");
		set.add("launch");
		set.add("project");
		set.add("component");
		set.add("pbd");
		set.add("jsp");

		return set;
	}

}
